package ar.uba.is2.ec.matem.algoritmo;

import java.util.Collection;

import org.apache.log4j.Logger;

import ar.uba.is2.common.mensaje.contenido.Dato;
import ar.uba.is2.common.mensaje.contenido.Identificador;
import ar.uba.is2.ec.matem.concurrent.DatoNoEncontradoCallback;
import ar.uba.is2.ec.matem.datos.ResultadoDeModelo;
import ar.uba.is2.ec.matem.motor.Regla;

public class AlgoritmoPrimeraRegla implements AlgoritmoConcurrente {

	private static final Logger logger = Logger.getLogger(AlgoritmoPrimeraRegla.class);
	
	private DatoNoEncontradoCallback callback;

	public void registrarCallback(DatoNoEncontradoCallback callback) {
		this.callback = callback;
	}

	@Override
	public ResultadoDeModelo ejecutar(String idModelo, Collection<Regla> reglas,
			Collection<Dato> datos) throws MissingDataException {
		
		try {
			Regla primeraRegla = reglas.iterator().next();
			
			Collection<Identificador> datosRequeridos = primeraRegla.getDatosRequeridos();
			
			checkDatosRequeridos(datosRequeridos, datos);
			
			ResultadoDeModelo resultado = primeraRegla.aplicar(datos);
			
			resultado.setIdModelo(idModelo);
			
			return resultado;
			
		} catch (InterruptedException e) {
			logger.warn(String.format("Algoritmo %s interrumpido", this.getClass()));
		}
		return null;
	}

	private void checkDatosRequeridos(Collection<Identificador> datosRequeridos,
			Collection<Dato> datos) throws InterruptedException, MissingDataException {

		
		for (Identificador id : datosRequeridos) {
			if (!esta(id,datos)){
				this.callback.doCallback(id, datos);
				if (!esta(id,datos)){
					throw new MissingDataException(String.format("No se pudo encontrar el dato %s", id));
				}
			}
		}
	}

	private boolean esta(Identificador id, Collection<Dato> datos) {
		for (Dato dato : datos) {
			if (dato.getIdentificador().equals(id))
				return true;
		}
		return false;
	}
	
}
